﻿/**
 * ...
 * @author Chase Kernan
 */

package com.chasekernan.hxnova.client;

import com.chasekernan.hxnova.client.mapviewer.IMapObject;
import com.chasekernan.hxnova.client.mapviewer.MapViewer;
import com.chasekernan.hxnova.utils.IntVector;
import com.chasekernan.hxnova.client.plugins.PluginManager;
import com.chasekernan.hxnova.utils.Vector;

class Selection {
    
    static var selected  = new Array<IMapObject>();
    static var listeners = new List<Void -> Void>();
    
    inline public static function getSelected() : Array<IMapObject> {
        return selected;
    }
    
    inline public static function getSingleSelection() : IMapObject {
        return selected[0];
    }
    
    inline public static function setSingleSelection(obj : IMapObject) {
        selected = [obj];
        callListeners();
    }
    
    inline public static function clearSelection() {
        selected = [];
        callListeners();
    }
    
    inline public static function setSelection(objs : Array<IMapObject>) {
        if (objs == null) clearSelection();
        else {
            selected = [];
            for (obj in objs) addSingle(obj);
            
            callListeners();
        }
    }
    
    static function addSingle(obj : IMapObject, ?toFront = false) {
        if (obj != null) {
            var found = false;
            
            for (match in selected) {
                if (match == obj) {
                    found = true;
                    break;
                }
            }
                
            if (!found) {
                if (toFront) selected.insert(0, obj);
                else         selected.push(obj);
            }
        }
    }
    
    public static function add(obj : IMapObject, ?toFront = false) {
        addSingle(obj, toFront);
        callListeners();
    }
    
    inline public static function remove(obj : IMapObject) : Bool {
        var removed = selected.remove(obj);
        if (removed) callListeners();
        return removed;
    }
    
    inline public static function removeAll(objs : Array<IMapObject>) {
        for (obj in objs) remove(obj);
        
        callListeners();
    }
    
    public static function isSelected(obj : IMapObject) : Bool {
        for (match in selected) {
            if (obj == match) return true;
        }
        
        return false;
    }
    
    public static function selectAll() {
        selected = getMap().getAllObjects();
        callListeners();
    }
    
    public static function circleSelect(point : Vector, radius : Float) {
        selected = [];
        for (obj in getMap().getAllObjects()) {
            if (obj.getObject().location.distanceTo(point) <= radius) add(obj);
        }
        
        callListeners();
    }
    
    public static function addListener(listener : Void -> Void) {
        listeners.push(listener);
    }
    
    public static function removeListener(listener : Void -> Void) {
        listeners.remove(listener);
    }
    
    inline static function callListeners() {
        for (listener in listeners) listener();
    }
    
    inline static function getMap() : MapViewer {
        var mapPlugin = PluginManager.getInstance().getPlugin("Map");
        return untyped mapPlugin.map;
    }
    
}